package com.cygsunri.wisdompark.socket;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.cygsunri.common.ConfigConstant;
import com.cygsunri.common.TuYaConstant;
import com.cygsunri.wisdompark.util.Byte16Util;
import com.cygsunri.wisdompark.util.CRCCheckUtil;
import com.cygsunri.wisdompark.util.HexAsciiUtil;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Set;

@Slf4j
@Component
@Order(value=2)
@PropertySource("classpath:configConstant.properties")
public class SocketService implements CommandLineRunner {
    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${init.socket}")
    private Boolean initSocket;

    @Value("${init.assciiToHex}")
    private Boolean assciiToHex;

    private static Set<Socket> socketSet = new HashSet();

    @Override
    public void run(String... args) throws Exception {
            new ServiceThread(initSocket,assciiToHex){}.start();
    }


    class ServiceThread extends Thread{
        private Boolean initSocket;
        private Boolean assciiToHex;

        public ServiceThread(Boolean initSocket,Boolean assciiToHex){
            this.initSocket = initSocket;
            this.assciiToHex = assciiToHex;
        }
        @Override
        public void run() {
            if(initSocket) {
                //初始化socket消息
                initializeSocketMessage();
                //启动socket服务端
                SocketService socketService = new SocketService();
                socketService.oneServer(assciiToHex);
            }
        }
    }


    public void oneServer(Boolean assciiToHex) {
        try {
            //1.创建一个服务器端Socket，即ServerSocket，指定绑定的端口，并监听此端口
            ServerSocket serverSocket = new ServerSocket(15200);
            Socket socket = null;
            log.info("***socket service begin start，wait client connect***");
            //循环监听等待客户端的连接
            while (true) {
                //调用accept()方法开始监听，等待客户端的连接
                socket = serverSocket.accept();
                //创建一个新的接收线程
                ServerThread serverThread = new ServerThread(socket,assciiToHex);
                serverThread.start();
                socketSet.add(socket);
                InetAddress address = socket.getInetAddress();
                log.info("the connect socket client IP：" + address.getHostAddress()+":"+socket.getPort());
            }
        } catch (Exception e) {
            log.info("can not listen to:" + e);
            //出错，打印出错信息
            e.printStackTrace();
        }
    }

    /**
     * 初始化socket消息
     */
    private void initializeSocketMessage(){
        byte[] bytes = Byte16Util.toByteArray("010300010005");
        String crcCheck = CRCCheckUtil.Make_CRC(bytes);
        String socketMessage = "010300010005"+crcCheck;
        redisTemplate.opsForValue().set("socketMessage",socketMessage);
    }


    /**
     * 定时任务执行给客户端发送消息
     */
    @Scheduled(cron="${constant.SocketSendMessageTask}")
    private void sendMessageTask() {
        log.info("begin socket service send Message");
        if(CollectionUtils.isNotEmpty(socketSet)){
            String message = redisTemplate.opsForValue().get("socketMessage").toString();
//            if(assciiToHex) {
//                message = HexAsciiUtil.hexToAscii(message);
//            }
            Set<Socket> tempSet = new HashSet() {};
            for(Socket socket: socketSet){
                if(!socket.isClosed()){
                    SendMessThread sendMessThread = new SendMessThread(socket,message);
                    sendMessThread.start();
                    tempSet.add(socket);
                }
            }
            socketSet = tempSet;
        }
    }



    public void sendMessage(String message) {
//        if(assciiToHex) {
//            message = HexAsciiUtil.hexToAscii(message);
//        }
        if(CollectionUtils.isNotEmpty(socketSet)){
            Set<Socket> tempSet = new HashSet() {};
            for(Socket socket: socketSet){
                if(!socket.isClosed()){
                    SendMessThread sendMessThread = new SendMessThread(socket,message);
                    sendMessThread.start();
                    tempSet.add(socket);
                }
            }
            socketSet = tempSet;
        }
    }

}